package game.Sokoban;

import game.Sokoban.Game.Level.Box;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;


public class Game {
	List<Level> levels =new ArrayList<Level>();
	
	public class Level{
		List<Box> boxes = new ArrayList<Box>();
		List<Wall> walls = new ArrayList<Wall>();
		List<Destination> destinations = new ArrayList<Destination>();
		Porter porter;
		
		public class Box{
			public int x;
			public int y;
			private GLSprite sprite;

			public void init(GLScene scene) {
				sprite = new GLSprite(x,y,1,1,0,"box");
			}

			public void draw(GLScene scene) {
					scene.add(sprite);
			}
			public void move(int x,int y) {
				this.x=x;
				this.y=y;
				sprite.x=x;
				sprite.y=y;
			}
		}

		public class Destination{
			public int x;
			public int y;
			private GLSprite sprite;

			public void init(GLScene scene) {
				sprite = new GLSprite(x,y,1,1,0,"destination");
			}

			public void draw(GLScene scene) {
					scene.add(sprite);
			}
		}
		
		public class Porter{
			int x;
			int y;
			private GLSprite sprite;
			
			public void draw(GLScene scene){
					scene.add(sprite);
			}

			public void init(GLScene scene) {
				sprite = new GLSprite(x,y,1,1,0,"porter");
			}

			public void move(int x,int y) {
				this.x=x;
				this.y=y;
				sprite.x=x;
				sprite.y=y;
			}
		}

		public class Wall{
			public int x;
			public int y;
			private GLSprite sprite;
			
			public void draw(GLScene scene){
					scene.add(sprite);
			}

			public void init(GLScene scene) {
				sprite = new GLSprite(x,y,1,1,0,"wall");
			}
		}

		private boolean wallsCollision(int x,int y){
			boolean flag=false;
			Iterator<Wall> i=walls.iterator();
			while(i.hasNext()){
				Wall wall=i.next();
				if((wall.x==x)&&(wall.y==y)) {
					Log.d("GAME","collision in{"+x+";"+y+"}");
					flag=true;
					}
			}
			return flag;
		}

		private Box boxesCollision(int x,int y){
			Box b=null;
			Iterator<Box> i=boxes.iterator();
			while(i.hasNext()){
				Box box=i.next();
				if((box.x==x)&&(box.y==y)) {
					Log.d("GAME","box collision in{"+x+";"+y+"}");
					b=box;
					}
			}
			return b;
		}

		
		public void init(GLScene scene){
			Iterator<Wall> iWall=walls.iterator();
			while(iWall.hasNext()){
				Wall wall=iWall.next();
				wall.init(scene);
			}

			Iterator<Destination> iDestination=destinations.iterator();
			while(iDestination.hasNext()){
				Destination destination=iDestination.next();
				destination.init(scene);
			}

			Iterator<Box> iBox=boxes.iterator();
			while(iBox.hasNext()){
				Box box=iBox.next();
				box.init(scene);
			}
			porter.init(scene);
		}

		public void draw(GLScene scene){
			
			//scene.add(new GLSprite(11,6,12,24,0,"background"));

			Iterator<Wall> iWall=walls.iterator();
			while(iWall.hasNext()){
				Wall wall=iWall.next();
				wall.draw(scene);
			}
			Iterator<Destination> iDestination=destinations.iterator();
			while(iDestination.hasNext()){
				Destination destination=iDestination.next();
				destination.draw(scene);
			}

			Iterator<Box> iBox=boxes.iterator();
			while(iBox.hasNext()){
				Box box=iBox.next();
				box.draw(scene);
			}
			porter.draw(scene);
		}
	}


	public GLScene scene;

	public void init(GL10 gl, Context context) {
		scene = new GLScene();
		scene.init(gl,context);
		scene.add(new GLTexture(gl,context,R.drawable.wall,"wall"));
		scene.add(new GLTexture(gl,context,R.drawable.android,"porter"));
		scene.add(new GLTexture(gl,context,R.drawable.destination1,"destination"));
		scene.add(new GLTexture(gl,context,R.drawable.box,"box"));
		//scene.add(new GLTexture(gl,context,R.drawable.background,"background"));
		levels.get(0).init(scene);
		initialized=true;
	}

	private boolean initialized=false;
	
	public void draw(GL10 gl) {
		if(initialized){
			scene.clear();
			//gl.glTranslatef(cameraX, cameraY, -15.0f);		// move camera 5 units INTO the screen
			levels.get(0).draw(scene);
			scene.draw();
		}
	}

	public void onKeyDown(int keyCode, KeyEvent event) {
		int x=levels.get(0).porter.x;
		int y=levels.get(0).porter.y;
		
		switch(keyCode)
	    {
        case KeyEvent.KEYCODE_DPAD_UP:{
        	Log.d("GAME","up");
    		if(!levels.get(0).wallsCollision(x,y+1)){
    			Box box=levels.get(0).boxesCollision(x,y+1);
    			if(box==null){
    				levels.get(0).porter.move(x,y+1);
    			}else{
    				if(!levels.get(0).wallsCollision(x,y+2) &&(levels.get(0).boxesCollision(x,y+2)==null)){
        				levels.get(0).porter.move(x,y+1);
        				box.move(x,y+2);
    				}
    			}
    		}
    		break;
   		}
        case KeyEvent.KEYCODE_DPAD_DOWN:{
        	Log.d("GAME","down");
    		if(!levels.get(0).wallsCollision(x,y-1)){
    			Box box=levels.get(0).boxesCollision(x,y-1);
    			if(box==null){
    				levels.get(0).porter.move(x,y-1);
    			}else{
    				if(!levels.get(0).wallsCollision(x,y-2) &&(levels.get(0).boxesCollision(x,y-2)==null)){
        				levels.get(0).porter.move(x,y-1);
        				box.move(x,y-2);
    				}
    			}
    		}
    		break;
   		}
        case KeyEvent.KEYCODE_DPAD_LEFT:{
        	Log.d("GAME","left");
    		if(!levels.get(0).wallsCollision(x-1,y)){
    			Box box=levels.get(0).boxesCollision(x-1,y);
    			if(box==null){
    				levels.get(0).porter.move(x-1,y);
    			}else{
    				if(!levels.get(0).wallsCollision(x-2,y) &&(levels.get(0).boxesCollision(x-2,y)==null)){
        				levels.get(0).porter.move(x-1,y);
        				box.move(x-2,y);
    				}
    			}
    		}
    		break;
   		}
        case KeyEvent.KEYCODE_DPAD_RIGHT:{
        	Log.d("GAME","right");
    		if(!levels.get(0).wallsCollision(x+1,y)){
    			Box box=levels.get(0).boxesCollision(x+1,y);
    			if(box==null){
    				levels.get(0).porter.move(x+1,y);
    			}else{
    				if(!levels.get(0).wallsCollision(x+2,y) &&(levels.get(0).boxesCollision(x+2,y)==null)){
        				levels.get(0).porter.move(x+1,y);
        				box.move(x+2,y);
    				}
    			}
    		}
    		break;
   		}
    }

    
	}
	
}
